﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Text.RegularExpressions;
using System.Data.Linq;
using System.Net;
using System.IO;

namespace SiteMonitorLogic
{
    /// <summary>
    /// A content check requests a page from the specified url and compares the result with a
    /// regular expression.  It also ensures that an HTTP OK code was returned.
    /// 
    /// The content check will not follow redirects.
    /// </summary>
    public class ContentCheck : ICheck
    {
        private string _name;
        private Uri _uri;
        private Regex _regex;
        private TimeSpan _timeout = new TimeSpan(0, 0, 20);
        private string _userAgent = "Grawl Site Monitor";

        /// <summary>
        /// Creates a new content check with the given configuration.
        /// </summary>
        /// <param name="configElement"></param>
        public ContentCheck(XElement configElement)
        {
            _name = configElement.Attribute("Name").Value;
            _uri = new Uri(configElement.Element("Uri").Value);
            _regex = new Regex(configElement.Element("RegularExpression").Value);

            if (configElement.Element("Timeout") != null)
                _timeout = TimeSpan.Parse(configElement.Element("Timeout").Value);

            if (configElement.Element("UserAgent") != null)
                _userAgent = configElement.Element("UserAgent").Value;
        }

        string ICheck.DisplayType
        {
            get { return "Content Check"; }
        }

        string ICheck.Name
        {
            get { return _name; }
        }

        string ICheck.Info
        {
            get
            {
                return _uri.ToString() + ", " + _regex.ToString();
            }
        }

        CheckResult ICheck.Execute()
        {
            try
            {
                // request
                HttpWebRequest req = (HttpWebRequest)WebRequest.Create(_uri);
                req.Timeout = (int)_timeout.TotalMilliseconds;
                req.UserAgent = _userAgent;

                Stream s = req.GetResponse().GetResponseStream();
                StreamReader sr = new StreamReader(s);
                string str = sr.ReadToEnd();
                
                // validate reg ex
                if (!_regex.IsMatch(str))
                {
                    return new CheckResult() { ResultCode = CheckResultCode.Failed, Message = "Regular expression did not match content." };
                }

                // success
                return new CheckResult() { ResultCode = CheckResultCode.Success, Message = "No error found." };
            }
            catch (Exception ex)
            {
                return new CheckResult() { ResultCode = CheckResultCode.Failed, Message = ex.GetType().ToString() + " - " + ex.Message };
            }
        }
    }
}
